﻿#include "GridBox.h"
#include "GridCell.h"
#include "defineNotice.h"

GridBox::GridBox(void)
{
    //line = NULL;
    //row = NULL;
   // bgImage = NULL;
   // width = NULL;
    //height = NULL;
    //slicesSize = 40;
    //cells->release();
    cells = NULL;
    //seeds = NULL;
   // xGap = NULL;
   // yGap = NULL;
}

GridBox::~GridBox(void)
{
    //line = NULL;
    //row = NULL;
   // bgImage = NULL;
    //width = NULL;
   // height = NULL;
    //slicesSize = NULL;
    setTouchEnabled(false);
}

void GridBox::setMatrix(int lines, int rows)
{
    this->lines = lines;
    this->rows = rows;

    createMatrix();
}

void GridBox::createMatrix()
{
    cells = CCArray::create();
    cells->retain();

    int sWidth = slicesSize.size.width;
    int sHeight = slicesSize.size.height;

    int width =  this->getContentSize().width;
    int height =  this->getContentSize().height;
    //统算出对应可用坐标点
    xGap = width / lines ;
    yGap = height / rows ;
    int x ,y;
	int zIndex = lines * rows - 1;
    for (int i = 0; i < rows ; i++)
    {
        CCArray * rows = CCArray::create();
        y = i * yGap  + yGap*.5 ;

        for (int j = 0 ; j < lines ; j++)
        {
            GridCell * pItem = GridCell::create();
            CC_BREAK_IF(! pItem);
            pItem->setLocation(new CCPoint( j,i));
            this->addChild(pItem, zIndex);
			zIndex--;

            x = j * xGap  + xGap*.5 ;

           // CCLOG("xy=>  %d  %d" , x , y);

            pItem->setPosition(ccp(x, y));

            rows->addObject(pItem);
        }
        cells->addObject(rows);
    }

}

GridBox * GridBox::create()
{
    GridBox * pRet = new GridBox();
    if (pRet && pRet->init())
    {
        pRet->setTouchEnabled(true);
        pRet->addNotificationCenter();
        pRet->launch();
    }
    else
    {
        CC_SAFE_DELETE(pRet);
    }
    return pRet;
}

bool GridBox::init()
{
    bool bRet = false;
    do
    {
        CC_BREAK_IF(! CCLayer::init());
        slicesSize = GridCell::slicesSize;
     
		CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect("hit.mp3");
		

        /* 验证坐标
        CCSprite * bg = CCSprite::create("001.png", GridCell::slicesSize);
        this->addChild(bg);

        CCSprite * bg2 = CCSprite::create("test001.png", GridCell::slicesSize);
        bg->addChild(bg2);
        */
        bRet = true;
    }
    while (0);
    return bRet;
}

void GridBox::addNotificationCenter()
{
    CCNotificationCenter::sharedNotificationCenter()->addObserver(this, callfuncO_selector(GridBox::onCellActionEnd), CELL_ACTION_END, NULL);
}

void GridBox::onCellActionEnd(CCObject * value)
{
    CCPoint * location = (CCPoint *)value;
    clearStep(location);
}

void GridBox::clearStep(CCPoint * location)
{
    int index = indexOfSeeds(location);
    if (index > -1)
    {
        clearStepAtIndex(index);
    }
}

void GridBox::clearStepAtIndex(int index)
{
    if (index > -1)
    {
        seeds.erase(seeds.begin()+index);
		CCLOG("len:  %d", 	seeds.size());
    }
}

int GridBox::indexOfSeeds(CCPoint * location)
{
    int index = -1;
    int len = seeds.size();
    for (int i = 0 ; i < len ; i++)
    {
        CCPoint * _location = (CCPoint *)seeds.at(i);
      //  CCLOG("if:  %f  %f   %f   %f", 	_location->x , location->x , _location->y , location->y);
        if (_location->x == location->x && _location->y == location->y)
        {
            index = i;
            break;
        }
        _location = NULL;
    }

    //CCLOG("len:  %d", 	seeds->count());
    return index;
}

void GridBox::launch()
{
    schedule(schedule_selector(GridBox::step), 0.7f);
    //CCPoint *c = (CCPoint *)seeds->objectAtIndex(0);
}

void GridBox::step(float dt)
{
	if (seeds.size() == rows*lines)
	{
		return;
	}
    int tRow = getRand(0, rows-1);
    int tLine = getRand(0, lines-1);

    CCPoint * cp = new CCPoint(tLine, tRow);
    int index = indexOfSeeds(cp);
    if (index == -1)
    {
		if (!cp)
		{
			CCLOG("cp------error!");
		}
	

       seeds.push_back(cp);

        GridCell * item = getItem(tLine, tRow);
        item->runningSusliks();
    }
    else
    {
        //step(dt);
    }
}

int GridBox::getRand(int start, int end )
{
    int r = rand()%(end-start+1)+start;
	r = 1;
    return r;
}

void GridBox::debug()
{
    ccColor3B color;
    color.r = 255;
    color.g = 0;
    color.b = 0;
    //setColor(color);
}
/*
void GridBox::registerWithTouchDispatcher(void) {
//	CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, kCCMenuHandlerPriority);
//	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority, true);
	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -128, true);
}
*/
void GridBox::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
    // 单点
    CCTouch *pTouch = (CCTouch*)(pTouches->anyObject());

    // 所有点
    for(CCSetIterator iterTouch = pTouches->begin(); iterTouch != pTouches->end(); iterTouch++)
    {
        CCTouch *pCurTouch =  (CCTouch*)(*iterTouch);
    }

    /*
    // 获取点在视图中的坐标（左上角为原点）
    CCPoint touchLocation = pTouch->getLocationInView();
    // 把点的坐标转换成OpenGL坐标（左下角为原点）
    touchLocation = CCDirector::sharedDirector()->convertToGL(touchLocation);
    // 把OpenGL的坐标转换成CCLayer的坐标
    CCPoint local = convertToNodeSpace(touchLocation);
    */
    CCPoint parentHit = this->getParent()->convertTouchToNodeSpace(pTouch);
    CCPoint local = convertTouchToNodeSpace(pTouch);

    if(isContainsPoint(parentHit) && isDisposeHitWin(local))
    {
        // 回调
        CCLog("WIN............................");
		playHitEffect();
		sendCellHitWin(pTouch);
    }
    else
    {
        // 不执行
        CCLog("LOSE............................");
    }
}


bool GridBox::isContainsPoint(CCPoint local)
{
    int width =  this->getContentSize().width;
    int height =  this->getContentSize().height;
    float aPointX = getAnchorPoint().x;
    float aPointY = getAnchorPoint().y;


    CCRect rect=this->boundingBox();

    bool flag = rect.containsPoint(local);
    return  flag;
}

GridCell * GridBox::getItem(int line, int row)
{
    CCArray * rows = (cocos2d::CCArray*)(cells->objectAtIndex(row));
    GridCell * item = (GridCell*)rows->objectAtIndex(line);
    return item;
}

/***************************************************
	2. 仅取指定范围内的对象来检测
	*************************************************/
bool GridBox::isDisposeHitWin(CCPoint local)
{
    bool flag = false;
    GridCell * item = NULL;
    CCRect * rect =NULL;
    // 取整
    int l_index = local.x / xGap ;
    int r_index = local.y / yGap ;

    CCPoint * pLocal =  new CCPoint(l_index ,r_index );
    int index = indexOfSeeds(pLocal);

    if ( index > -1)
    {
        item = getItem(l_index, r_index);
        rect = item->getHitRect();
        if (rect->containsPoint(local))
        {
            flag = true;
			clearStepAtIndex(index);
        }
    }
	item->setHitWin(flag);
    return flag;
}

void GridBox::playHitEffect()
{
	CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("hit.mp3");
}

void GridBox::sendCellHitWin(CCTouch *pTouch)
{
	CCNotificationCenter::sharedNotificationCenter()->postNotification(PLAYER_HIT_WIN ,((CCObject *)pTouch));
}
